package com.uduemc.biso.node.web.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageInfo;
import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.node.core.common.entities.BaiduUrls;
import com.uduemc.biso.node.core.entities.HBaiduApi;
import com.uduemc.biso.node.core.entities.HBaiduUrls;
import com.uduemc.biso.node.core.entities.HDomain;
import com.uduemc.biso.node.core.feign.HBaiduApiFeign;
import com.uduemc.biso.node.core.feign.HBaiduUrlsFeign;
import com.uduemc.biso.node.core.utils.RestResultUtil;
import com.uduemc.biso.node.web.api.component.ExternalApi;
import com.uduemc.biso.node.web.api.component.RequestHolder;
import com.uduemc.biso.node.web.api.pojo.ResponseBaiduUrls;
import com.uduemc.biso.node.web.api.pojo.external.RspBaiduApiUrls;
import com.uduemc.biso.node.web.api.service.BaiduApiService;
import com.uduemc.biso.node.web.api.service.DomainService;
import com.uduemc.biso.node.web.api.service.HostService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;

@Service
@Slf4j
public class BaiduApiServiceImpl implements BaiduApiService {

    @Resource
    private HBaiduApiFeign hBaiduApiFeign;

    @Resource
    private HBaiduUrlsFeign hBaiduUrlsFeign;

    @Resource
    private RequestHolder requestHolder;

    @Resource
    private ExternalApi externalApi;

    @Resource
    private DomainService domainServiceImpl;

    @Resource
    private HostService hostServiceImpl;

    @Resource
    private ObjectMapper objectMapper;

    @Override
    public HBaiduApi infoByDomainId(Long domainId)
            throws IOException {
        Long hostId = requestHolder.getHost().getId();
        RestResult restResult = hBaiduApiFeign.findNoCreateByHostDomainId(hostId, domainId);
        HBaiduApi data = RestResultUtil.data(restResult, HBaiduApi.class);
        return data;
    }

    @Override
    public HBaiduApi saveZztokenByDomainId(Long domainId, String zzToken)
            throws IOException {
        Long hostId = requestHolder.getHost().getId();
        RestResult restResult = hBaiduApiFeign.saveZzToken(hostId, domainId, zzToken);
        HBaiduApi data = RestResultUtil.data(restResult, HBaiduApi.class);
        return data;
    }

    @Override
    public JsonResult testBaiduZztoken(HBaiduApi hBaiduApi)
            throws IOException {
        JsonResult result = JsonResult.assistance();
        if (hBaiduApi == null) {
            result = JsonResult.assistance();
        } else {
            if (StrUtil.isEmpty(hBaiduApi.getZzToken())) {
                hBaiduApi.setZzStatus((short) 2);
                result = JsonResult.messageError("没有绑定 token ！");
            } else {
                Long hostId = requestHolder.getHost().getId();
                HDomain hDomain = domainServiceImpl.infoByIdHostId(hBaiduApi.getDomainId(), hostId);
                if (hDomain == null) {
                    hBaiduApi.setZzStatus((short) 2);
                    result = JsonResult.assistance();
                } else {
                    String baiduUrls = externalApi.baiduUrls(hDomain.getDomainName(), hBaiduApi.getZzToken(),
                            "http://" + hDomain.getDomainName() + "/index.html");
                    if (StrUtil.isBlank(baiduUrls)) {
                        log.info("testBaiduZztoken baiduUrls: " + baiduUrls);
                        hBaiduApi.setZzStatus((short) 2);
                        result = JsonResult.assistance();
                    } else {
                        RspBaiduApiUrls readValue = null;
                        try {
                            readValue = objectMapper.readValue(baiduUrls, RspBaiduApiUrls.class);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        if (readValue == null) {
                            result = JsonResult.messageError("测试绑定的 token 异常！");
                        } else {
                            if (readValue.getSuccess() > 0) {
                                hBaiduApi.setZzStatus((short) 1);
                                result = JsonResult.messageSuccess("测试成功！");
                            } else {
                                if (StrUtil.isBlank(readValue.getMessage())) {
                                    log.info("testBaiduZztoken baiduUrls: " + baiduUrls);
                                    hBaiduApi.setZzStatus((short) 2);
                                    result = JsonResult.assistance();
                                } else {
                                    hBaiduApi.setZzStatus((short) 2);
                                    String message = readValue.getMessage();
                                    if (message.equals("site error")) {
                                        message = "绑定的域名（" + hDomain.getDomainName() + "）无效";
                                    } else if (message.equals("token is not valid")) {
                                        message = "绑定的token（" + hBaiduApi.getZzToken() + "）无效";
                                    }
                                    result = JsonResult.messageError(message);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (hBaiduApi != null) {
            hBaiduApiFeign.updateById(hBaiduApi);
            result.setData(hBaiduApi);
        }
        return result;
    }

    @Override
    public JsonResult testBaiduZztoken(Long domainId)
            throws IOException {
        HBaiduApi hBaiduApi = infoByDomainId(domainId);
        return testBaiduZztoken(hBaiduApi);
    }

    @Override
    public JsonResult testBaiduZztoken(Long domainId, String zzToken)
            throws IOException {
        HBaiduApi hBaiduApi = infoByDomainId(domainId);
        if (hBaiduApi.getZzToken().equals(zzToken)) {
            return testBaiduZztoken(hBaiduApi);
        }
        HBaiduApi saveHBaiduApi = saveZztokenByDomainId(domainId, zzToken);
        if (saveHBaiduApi == null) {
            return JsonResult.assistance();
        }
        return testBaiduZztoken(saveHBaiduApi);
    }

    @Override
    public List<HBaiduApi> existWithinEightHours()
            throws IOException {
        RestResult restResult = hBaiduApiFeign.existWithinEightHours();
        @SuppressWarnings("unchecked")
        List<HBaiduApi> data = (List<HBaiduApi>) RestResultUtil.data(restResult, new TypeReference<List<HBaiduApi>>() {
        });
        return data;
    }

    @Override
    public List<HBaiduApi> existWithinOneDay()
            throws IOException {
        RestResult restResult = hBaiduApiFeign.existWithinOneDay();
        @SuppressWarnings("unchecked")
        List<HBaiduApi> data = (List<HBaiduApi>) RestResultUtil.data(restResult, new TypeReference<List<HBaiduApi>>() {
        });
        return data;
    }

    @Override
    public void insertBaiduUrls(String urls, HBaiduApi hBaiduApi, RspBaiduApiUrls rspBaiduApiUrls)
            throws IOException {
        Long hostId = hBaiduApi.getHostId();
        Long domainId = hBaiduApi.getDomainId();
        int success = rspBaiduApiUrls.getSuccess();
        int remain = rspBaiduApiUrls.getRemain();
        List<String> not_same_site = rspBaiduApiUrls.getNot_same_site();
        List<String> not_valid = rspBaiduApiUrls.getNot_valid();
        int error = rspBaiduApiUrls.getError();
        String message = rspBaiduApiUrls.getMessage();
        String rsp = objectMapper.writeValueAsString(rspBaiduApiUrls);
        short status = -1;
        if (success != -1) {
            status = 1;
        } else {
            status = 2;
        }

        String notSameSite = "";
        if (CollUtil.isNotEmpty(not_same_site)) {
            notSameSite = CollUtil.join(not_same_site, "\n");
        }

        String notValid = "";
        if (CollUtil.isNotEmpty(not_valid)) {
            notValid = CollUtil.join(not_valid, "\n");
        }

        HBaiduUrls hBaiduUrls = new HBaiduUrls();
        hBaiduUrls.setHostId(hostId).setDomainId(domainId).setStatus(status).setUrls(urls).setSuccess(success)
                .setRemain(remain).setNotSameSite(notSameSite).setNotValid(notValid).setError(error).setMessage(message)
                .setRsp(rsp);

        hBaiduUrlsFeign.insert(hBaiduUrls);
    }

    @Override
    public void pushBaiduUrls(HBaiduApi hBaiduApi)
            throws IOException {
        if (hBaiduApi.getZzStatus().shortValue() != (short) 1) {
            return;
        }
        if (StrUtil.isBlank(hBaiduApi.getZzToken())) {
            return;
        }
        HDomain hDomain = domainServiceImpl.infoByIdHostId(hBaiduApi.getDomainId(), hBaiduApi.getHostId());
        if (hDomain == null) {
            return;
        }

        // 获取构建好的 urls
        List<String> hostUrls = hostServiceImpl.hostUrls(hBaiduApi.getHostId(), hBaiduApi.getDomainId());
        if (CollUtil.isEmpty(hostUrls)) {
            return;
        }
        String urls = CollUtil.join(hostUrls, "\n");

        String baiduUrls = externalApi.baiduUrls(hDomain.getDomainName(), hBaiduApi.getZzToken(), urls);

        if (StrUtil.isBlank(baiduUrls)) {
            log.info("pushBaiduUrls baiduUrls: " + baiduUrls);
        } else {
            RspBaiduApiUrls readValue;
            try {
                readValue = objectMapper.readValue(baiduUrls, RspBaiduApiUrls.class);
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            if (StrUtil.isBlank(readValue.getMessage())) {
                log.info("pushBaiduUrls baiduUrls: " + baiduUrls);
            }
            insertBaiduUrls(urls, hBaiduApi, readValue);
        }
    }

    @Override
    public void pushBaiduUrls() throws IOException {
        List<HBaiduApi> listHBaiduApi = existWithinOneDay();
        if (CollUtil.isNotEmpty(listHBaiduApi)) {
            for (HBaiduApi hBaiduApi : listHBaiduApi) {
                pushBaiduUrls(hBaiduApi);
            }
        }
    }

    @Override
    public ResponseBaiduUrls infosBaiduUrls(long domainId, short status, int page, int pagesize)
            throws IOException {
        Long hostId = requestHolder.getHost().getId();
        RestResult restResult = hBaiduUrlsFeign.findBaiduUrlsByHostDomainIdAndStatus(hostId, domainId, status, page,
                pagesize);
        @SuppressWarnings("unchecked")
        PageInfo<BaiduUrls> pageInfoBaiduUrls = (PageInfo<BaiduUrls>) RestResultUtil.data(restResult,
                new TypeReference<PageInfo<BaiduUrls>>() {
                });
        ResponseBaiduUrls make = ResponseBaiduUrls.make(pageInfoBaiduUrls);
        return make;
    }

}
